package controller;

import dao.FileContentDao;
import dao.FileInformationDao;
import model.FileContent;
import model.FileInformation;
import util.*;
import view.MainView;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.util.Date;
import java.util.LinkedList;
import java.util.UUID;

/**
 * PackageName: controller
 * ClassName: ButtonActionListener
 * Author: tum0r
 * Time: 2020/5/24 10:16
 */
public class ButtonActionListener implements ActionListener {
    private MainView view;
    private FileChooser fileChooser;

    private LinkedList<String> path;
    private String dirPath;
    private String labelsPath;
    private String resourceDBPath;
    private FileOperator fileOperator = new FileOperator();
    private FileInformationDao fileInformationDao = new FileInformationDao();
    private FileContentDao fileContentDao = new FileContentDao();
    private String[] fileID;
    private int successCount;
    private int failCount;

    public ButtonActionListener(MainView view) {
        this.view = view;
        fileChooser = new FileChooser(view);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        switch (e.getActionCommand()) {
            case "选 择\u200B":
                path = fileChooser.open(JFileChooser.DIRECTORIES_ONLY, false);
                if (path.size() > 0) {
                    view.setIODirPath(path.get(0));
                }
                path.clear();
                break;
            case "创建标签文件":
                dirPath = view.getIODirPath();
                if (dirPath != null && dirPath.trim().length() != 0) {
                    view.setProgress(null, "正在递归读取%s下的文件", dirPath);
                    path = fileOperator.getAllFiles(dirPath);
                    view.setProgress(null, "%s下的文件读取完成，共计%d个文件，正在准备写入Label文件", dirPath, path.size());
                    labelsPath = view.getLabelsPath();
                    if (labelsPath == null || labelsPath.trim().length() == 0) {
                        view.setProgress(Config.PROGRESS_LABEL_FONT_COLOR_ERROR, "必须选择Labels文件路径");
                        labelsPath = fileChooser.save("Labels文本文件(*.txt)", "txt");
                        view.setLabelsPath(labelsPath);
                    } else {
                        File file = new File(labelsPath);
                        if (file.exists()) {
                            file.delete();
                        }
                        for (int i = 0; i < path.size(); i++) {
                            try {
                                fileOperator.writeFile(labelsPath, path.get(i) + " = " + Config.LINE);
                                view.setProgress(null, "%s写入完成，当前进度    %d/%d    %.2f%%", path.get(i), i, path.size(), (double) i / path.size() * 100);
                            } catch (IOException ioException) {
                                ioException.printStackTrace();
                            }
                        }
                        view.setProgress(null, "共写入%d个文件", path.size());
                    }
                } else {
                    view.setProgress(Config.PROGRESS_LABEL_FONT_COLOR_ERROR, "必须选择输入/输出文件夹");
                }
                break;
            case "选 择\u200B\u200B":
                path = fileChooser.open(JFileChooser.FILES_ONLY, false, "Labels文本文件(*.txt)", "txt");
                if (path.size() > 0) {
                    view.setLabelsPath(path.get(0));
                }
                break;
            case "写入资源":
                labelsPath = view.getLabelsPath();
                if (labelsPath != null && labelsPath.trim().length() != 0) {
                    resourceDBPath = view.getResourcesPath();
                    if (resourceDBPath != null && resourceDBPath.trim().length() != 0) {
                        WriteThread writeThread = new WriteThread(labelsPath, resourceDBPath, view);
                        Thread thread = new Thread(writeThread);
                        thread.start();
                    } else {
                        view.setProgress(Config.PROGRESS_LABEL_FONT_COLOR_ERROR, "必须选择数据库文件");
                    }
                } else {
                    view.setProgress(Config.PROGRESS_LABEL_FONT_COLOR_ERROR, "必须选择标签文件");
                }
                break;
            case "选 择\u200B\u200B\u200B":
                path = fileChooser.open(JFileChooser.FILES_ONLY, false, "SQLite数据库文件(*.db)", "db");
                if (path.size() > 0) {
                    view.setResourcesPath(path.get(0));
                }
                break;
            case "创建数据库":
                resourceDBPath = view.getResourcesPath();
                if (resourceDBPath == null || resourceDBPath.trim().length() == 0) {
                    resourceDBPath = fileChooser.save("数据库文件案(*.db)", "db");
                    if (resourceDBPath != null) {
                        view.setResourcesPath(resourceDBPath);
                        try {
                            fileInformationDao.open(resourceDBPath);
                            fileInformationDao.commit();
                            fileInformationDao.close();
                            view.setProgress(null, "创建数据库成功");
                        } catch (ClassNotFoundException | SQLException classNotFoundException) {
                            view.setProgress(Config.PROGRESS_LABEL_FONT_COLOR_ERROR, "创建数据库失败");
                            classNotFoundException.printStackTrace();
                        }
                    } else {
                        view.setProgress(Config.PROGRESS_LABEL_FONT_COLOR_ERROR, "创建数据库失败");
                    }
                }
                break;
            case "搜 索":
                resourceDBPath = view.getResourcesPath();
                if (resourceDBPath != null && resourceDBPath.trim().length() != 0) {
                    try {
                        if (fileInformationDao.open(resourceDBPath)) {
                            String[] keys = view.getSearchText();
                            LinkedList<FileInformation> files = fileInformationDao.search(keys);
                            fileInformationDao.close();
                            view.setProgress(null, "搜索完成，共有%d条结果", files.size());
                            view.setSearchResult(files);
                        } else {
                            view.setProgress(Config.PROGRESS_LABEL_FONT_COLOR_ERROR, "数据库打开失败");
                        }
                    } catch (SQLException | ClassNotFoundException throwables) {
                        view.setProgress(Config.PROGRESS_LABEL_FONT_COLOR_ERROR, "数据库打开失败");
                        throwables.printStackTrace();
                    }
                } else {
                    view.setProgress(Config.PROGRESS_LABEL_FONT_COLOR_ERROR, "需要选择数据库");
                }
                break;
            case "提取文件":
                dirPath = view.getIODirPath();
                resourceDBPath = view.getResourcesPath();
                fileID = view.getFileID();
                if (dirPath != null && dirPath.trim().length() != 0) {
                    if (resourceDBPath != null && resourceDBPath.trim().length() != 0) {
                        ExtractThread extractThread = new ExtractThread(dirPath, fileID, resourceDBPath, view);
                        Thread thread = new Thread(extractThread);
                        thread.start();
                    } else {
                        view.setProgress(Config.PROGRESS_LABEL_FONT_COLOR_ERROR, "需要选择数据库");
                    }
                } else {
                    view.setProgress(Config.PROGRESS_LABEL_FONT_COLOR_ERROR, "需要选择输出文件夹");
                }
                break;
            case "删除文件":
                resourceDBPath = view.getResourcesPath();
                fileID = view.getFileID();
                if (resourceDBPath != null && resourceDBPath.trim().length() != 0) {
                    boolean flag;
                    if (fileID == null || fileID.length == 0) {
                        flag = JOptionPane.showConfirmDialog(view, "你正在清空数据库，清空后不可恢复，请确认操作", "!!! 警告 !!!", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
                    } else {
                        flag = JOptionPane.showConfirmDialog(view, "你正在删除文件，删除后不可恢复，请确认操作", "!!! 警告 !!!", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
                    }
                    if (flag) {
                        try {
                            if (fileInformationDao.open(resourceDBPath)) {
                                int count = fileInformationDao.delete(fileID);
                                if (count != 0) {
                                    fileInformationDao.commit();
                                    view.setProgress(null, "删除资源成功，共计删除%d条", count);
                                } else {
                                    fileInformationDao.rollback();
                                    view.setProgress(Config.PROGRESS_LABEL_FONT_COLOR_ERROR, "删除资源失败，已回滚");
                                }
                                fileInformationDao.close();
                            } else {
                                view.setProgress(Config.PROGRESS_LABEL_FONT_COLOR_ERROR, "数据库打开失败");
                            }
                        } catch (SQLException | ClassNotFoundException throwables) {
                            throwables.printStackTrace();
                        }
                    }
                } else {
                    view.setProgress(Config.PROGRESS_LABEL_FONT_COLOR_ERROR, "需要选择数据库");
                }
                break;
        }
    }
}
